/*
 * @Author: your name
 * @Date: 2022-02-04 13:26:22
 * @LastEditTime: 2022-02-04 13:40:50
 * @LastEditors: Please set LastEditors
 * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 * @FilePath: \ts\05接口和类型别名区别.ts
 */
// 接口和类型别名差不多， 区别在于接口只能定义成对象， 而类型别名可以单独定义值
// 1.接口(Interface)
// 接口主要用于类型检查，它只是一个结构契约，定义了具有相似的名称和类型的对象结构。除此之外，接口还可以定义方法和事件。

// 2.类型别名(Type Alias)
// 不同于interface只能定义对象类型，type声明还可以定义基础类型、联合类型或交叉类型。

//基本类型
type test = number;
let num: test = 10;

type userOjb = { name: string } // 对象


// 函数,
type getName = () => string  // 函数,返回string
const getNameFn: getName = () => {
    return '123'
}
getNameFn()

// 函数2
type User = {
    name: string
    age: number
};
type SetUser = (name: string, age: number) => void;


// 元组
type data = [number, string]
const datas: data = [1, '2']


// 联合类型
interface Second {
    name: string
}
// 接口只能以对象形式
interface intert {
    age: number
}
type numOrFun = Second | intert
type numOrFun1 = Second | getName  // 方法也可以
const si: numOrFun = { age: 1 }



// 扩展和实现(extends & implement)
// interface可以扩展，type可以通过交叉实现interface的extends行为
// interface可以extends type，同时type也可以与interface类型交叉
interface Name1 {
    name: string;
}
interface User1 extends Name1 {
    age: number
}
let stu1: User = { name: 'wang', age: 10 }


//interface的扩展可以通过type交叉(&)类型实现
type Name2 = {
    name: string;
}
type User2 = Name2 & { age: number }
let stu2: User = { name: 'wang', age: 18 }


//interface 扩展 type
type Name3 = {
    name: string;
}
interface User3 extends Name3 {
    age: number;
}
let stu3: User3 = { name: 'wang', age: 89 }


//type与interface交叉
interface Name4 {
    name: string;
}
type User4 = Name4 & {
    age: number;
}
let stu4: User4 = { name: 'wang', age: 18 }


//   映射类型
// {type 能使用 in 关键字生成映射类型，但interface不行}

type Keys = "name" | "sex"

type DuKey = {
    [Key in Keys]: string //类似 for ... in
}
let stu5: DuKey = {
    name: 'wang',
    sex: 'man'
}